/*
  学习目标：无感刷新-小结
  1. token是用来请求业务数据的， 时效短
  2. refresh_token的作用， 请求新的token， 时效长

  逻辑：
    1. 401的情况分三种
    1.1 token不存在 ✅ 无需处理， 鉴权路由会拦截组件渲染， 不会发请求
    1.2 token存在，但过期
      1.2.1 token过期，refresh_token请求新的token
       ✅ 刷新新的token
       ✅ 用新的token，请求之前失败的请求
      1.2.2 token过期，refresh_token也过期
       ✅ 重定向到登录界面， 提示用户， 删除token

*/

import { Toast } from 'antd-mobile';

import history from './history';
import { getAuth } from './storage';
import axios from 'axios';
import { saveAuth } from '@/utils/storage';
import { removeAuth } from '@/utils/storage';

// 请求基地址
export const baseURL = 'http://toutiao.itheima.net/';

const http = axios.create({
  baseURL: baseURL,
  timeout: 5000,
});

// 请求拦截器
http.interceptors.request.use(
  function (config: any) {
    const { token } = getAuth();
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  function (error) {
    return Promise.reject(error);
  }
);

// 响应拦截器
http.interceptors.response.use(
  function (response) {
    return response.data;
  },
  async function (error) {
    console.dir(error);
    if (!error.response) {
      Toast.show('网路有问题, 请检查网络');
      return Promise.reject(error);
    }

    if (error.response.status !== 401) {
      Toast.show(error.response.data.message);
      return Promise.reject(error);
    }

    const { refresh_token } = getAuth();
    if (!refresh_token) {
      history.push('/login');
      removeAuth();
      Toast.show('登录失效, 请重新登录');
      return Promise.reject(error);
    }

    try {
      const res = await axios({
        url: 'http://geek.itheima.net/v1_0/authorizations',
        method: 'put',
        headers: { Authorization: `Bearer ${refresh_token}` },
      });

      saveAuth({
        refresh_token,
        token: res.data.data.token,
      });

      // 获取到新的token后， 发起之前失败的请求
      return http({
        url: error.config.url,
        method: error.config.method,
        data: error.config.data,
        params: error.config.params,
      });
    } catch (err) {
      // 刷新token的请求报错， 重定向到登录界面， 提示用户
      history.push('/login');
      removeAuth();
      Toast.show('登录失效, 请重新登录');
      return Promise.reject(error);
    }

    // http(error.config);
  }
);

export default http;
